<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Java games moving sprites</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Java, Swing, tutorial, games, moving sprites, programming, GUI, multiplatform">
<meta name="description" content="This part of the Java games tutorial works with moving sprites.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Moving sprites</h1>

<p>
In this part of the Java 2D games tutorial we will work with sprites. 
</p>

<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* LargeSquare */
google_ad_slot = "5070696322";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

<p>
The term <b>sprite</b> has several meanings. It is used to denote an image 
or an animation in a scene. It is also used to represent any movable object 
in a game. Also one of the meanings is the code that encapsulates a character in a game. 
In our tutorial by using sprite we refer to a movable object or its java class. 
</p>


<h2>R-Type</h2>

<p>
In the first example we will have a spacecraft. We can move the spacecraft 
on the board using the cursor keys. 
</p>

<div class="codehead">Craft.java</div>
<pre class="code">
package rtype;

import java.awt.Image;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;

public class Craft {

    private String craft = "craft.png";

    private int dx;
    private int dy;
    private int x;
    private int y;
    private Image image;

    public Craft() {
        ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
        image = ii.getImage();
        x = 40;
        y = 60;
    }


    public void move() {
        x += dx;
        y += dy;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public Image getImage() {
        return image;
    }

    public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = -1;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 1;
        }

        if (key == KeyEvent.VK_UP) {
            dy = -1;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 1;
        }
    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_UP) {
            dy = 0;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 0;
        }
    }
}
</pre>

<p>
This class represents a spacecraft. In this class we keep the image of 
the sprite and the coordinates of the sprite. The keyPressed() and keyReleased()
methods control whether the sprite is moving or is in standstill.  
</p>

<pre class="explanation">
public void move() {
    x += dx;
    y += dy;
}
</pre>

<p>
The move() method changes the coordinates of the sprite. 
These x, y values are used in the paint() method to draw 
the image of the sprite.  
</p>


<pre class="explanation">
if (key == KeyEvent.VK_LEFT) {
    dx = 0;
}
</pre>

<p>
When we release the left cursor key, we set the <b>dx</b> variable to zero. 
The spacecraft will stop moving. 
</p>

<div class="codehead">Board.java</div>
<pre class="code">
package rtype;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JPanel;
import javax.swing.Timer;


public class Board extends JPanel implements ActionListener {

    private Timer timer;
    private Craft craft;

    public Board() {

        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);

        craft = new Craft();

        timer = new Timer(5, this);
        timer.start();
    }


    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);

        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }


    public void actionPerformed(ActionEvent e) {
        craft.move();
        repaint();  
    }


    private class TAdapter extends KeyAdapter {

        public void keyReleased(KeyEvent e) {
            craft.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            craft.keyPressed(e);
        }
    }

}
</pre>

<p>
This is the Board class. 
</p>

<pre class="explanation">
g2d.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);
</pre>

<p>
In the paint() method, we draw the spacecraft. We get the image and the
coordinates from the sprite class. 
</p>

<pre class="explanation">
public void actionPerformed(ActionEvent e) {
    craft.move();
    repaint();  
}
</pre>

<p>
The actionPerformed() method is called every 5ms. We move the sprite and repaint the board. 
</p>

<div class="codehead">RType.java</div>
<pre class="code">
package rtype;

import javax.swing.JFrame;

public class RType extends JFrame {

    public RType() {

        add(new Board());

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);
        setTitle("R - Type");
        setResizable(false);
        setVisible(true);
    }

    public static void main(String[] args) {
        new RType();
    }
}
</pre>

<p>
This is the main class. 
</p>


<img src="/img/gfx/javagames/rtype.png" alt="R-Type">
<div class="figure">Figure: R-Type</div>



<h2>Shooting missiles</h2>

<p>
In the next example we will add another sprite type to our example. A missile. 
We can launch missiles with the space key. 
</p>

<div class="codehead">Missile.java</div>
<pre class="code">
package rtype;

import java.awt.Image;

import javax.swing.ImageIcon;

public class Missile {

    private int x, y;
    private Image image;
    boolean visible;

    private final int BOARD_WIDTH = 390;
    private final int MISSILE_SPEED = 2;

    public Missile(int x, int y) {

        ImageIcon ii =
            new ImageIcon(this.getClass().getResource("missile.png"));
        image = ii.getImage();
        visible = true;
        this.x = x;
        this.y = y;
    }


    public Image getImage() {
        return image;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public boolean isVisible() {
        return visible;
    }

    public void move() {
        x += MISSILE_SPEED;
        if (x > BOARD_WIDTH)
            visible = false;
    }
}
</pre>

<p>
Here we have a new sprite called Missile. 
</p>

<pre class="explanation">
public void move() {
    x += MISSILE_SPEED;
    if (x > BOARD_WIDTH)
        visible = false;
}
</pre>

<p>
The missile moves at constant speed. When it hits the right border of the 
Board, it becomes invisible. It is then removed from the ArrayList of missiles. 
</p>

<div class="codehead">Craft.java</div>
<pre class="code">
package rtype;

import java.awt.Image;
import java.awt.event.KeyEvent;

import java.util.ArrayList;

import javax.swing.ImageIcon;

public class Craft {

    private String craft = "craft.png";

    private int dx;
    private int dy;
    private int x;
    private int y;
    private Image image;

    private ArrayList missiles;

    private final int CRAFT_SIZE = 20;

    public Craft() {
        ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
        image = ii.getImage();
        missiles = new ArrayList();
        x = 40;
        y = 60;
    }


    public void move() {
        x += dx;
        y += dy;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public Image getImage() {
        return image;
    }

    public ArrayList getMissiles() {
        return missiles;
    }

    public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_SPACE) {
            fire();
        }

        if (key == KeyEvent.VK_LEFT) {
            dx = -1;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 1;
        }

        if (key == KeyEvent.VK_UP) {
            dy = -1;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 1;
        }
    }

    public void fire() {
        missiles.add(new Missile(x + CRAFT_SIZE, y + CRAFT_SIZE/2));
    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_UP) {
            dy = 0;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 0;
        }
    }
}
</pre>

<p>
The Craft.java has changed a bit. 
</p>

<pre class="explanation">
if (key == KeyEvent.VK_SPACE) {
    fire();
}
</pre>

<p>
If we press the space key, we fire. 
</p>


<pre class="explanation">
public void fire() {
    missiles.add(new Missile(x + CRAFT_SIZE, y + CRAFT_SIZE/2));
}
</pre>

<p>
The fire() method creates a new Missile object and adds it to the missiles ArrayList. 
</p>

<pre class="explanation">
 public ArrayList getMissiles() {
     return missiles;
 }
</pre>

<p>
The getMissiles() method returns the ArrayList of missiles. 
It is called from the Board class. 
</p>

<div class="codehead">Board.java</div>
<pre class="code">
package rtype;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import java.util.ArrayList;

import javax.swing.JPanel;
import javax.swing.Timer;


public class Board extends JPanel implements ActionListener {

    private Timer timer;
    private Craft craft;

    public Board() {

        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);

        craft = new Craft();

        timer = new Timer(5, this);
        timer.start();
    }


    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);

        ArrayList ms = craft.getMissiles();

        for (int i = 0; i &lt; ms.size(); i++ ) {
            Missile m = (Missile) ms.get(i);
            g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
        }

        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }


    public void actionPerformed(ActionEvent e) {
        ArrayList ms = craft.getMissiles();

        for (int i = 0; i &lt; ms.size(); i++) {
            Missile m = (Missile) ms.get(i);
            if (m.isVisible()) 
                m.move();
            else ms.remove(i);
        }

        craft.move();
        repaint();  
    }


    private class TAdapter extends KeyAdapter {

        public void keyReleased(KeyEvent e) {
            craft.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            craft.keyPressed(e);
        }
    }
}
</pre>

<p>
This is the Board.java file. 
</p>

<pre class="explanation">
ArrayList ms = craft.getMissiles();

for (int i = 0; i &lt; ms.size(); i++ ) {
    Missile m = (Missile) ms.get(i);
    g2d.drawImage(m.getImage(), m.getX(), m.getY(), this);
}
</pre>

<p>
In the paint() method we draw all missiles from the array list.
</p>

<pre class="explanation">
ArrayList ms = craft.getMissiles();
for (int i = 0; i &lt; ms.size(); i++) {
    Missile m = (Missile) ms.get(i);
    if (m.isVisible()) 
        m.move();
    else ms.remove(i);
}
</pre>

<p>
In the actionPerformed() method we parse all missiles 
from the array list. Depending on the visible flag, we move the missile 
or remove it from the container. 
</p>

<div class="codehead">RType.java</div>
<pre class="code">
package rtype;

import javax.swing.JFrame;

public class RType extends JFrame {

    public RType() {

        add(new Board());

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);
        setTitle("R - Type");
        setResizable(false);
        setVisible(true);
    }

    public static void main(String[] args) {
        new RType();
    }
}
</pre>

<p>
Finally, this is the main class. 
</p>


<img src="/img/gfx/javagames/missiles.png" alt="Shooting missiles">
<div class="figure">Figure: Shooting missiles</div>


<p>
In this chapter, we have covered sprites.
</p>


<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>

<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified September 28, 2008  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

